package com.jp.knowledge.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.os.Environment;

import com.jp.knowledge.logic.UploadLogic;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/* 多图上传 */
public class MultipleImageUploader {

    private Context context;
    private List<ImageBean> imageBeen;
    private int compressQuality;
    private String cacheImageDir;
    private boolean cleanCacheAfterUpload;

    public MultipleImageUploader(Context context){
        this(context, 30, true);
    }
    public MultipleImageUploader(Context context, int compressQuality){
        this(context, compressQuality, true);
    }
    public MultipleImageUploader(Context context, boolean cleanCacheAfterUpload){
        this(context, 30, cleanCacheAfterUpload);
    }
    public MultipleImageUploader(Context context, int compressQuality, boolean cleanCacheAfterUpload){
        this.context = context;
        imageBeen = new ArrayList<>();
        this.compressQuality = compressQuality;
        this.cleanCacheAfterUpload = cleanCacheAfterUpload;
        this.cacheImageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/team_circle_upload/";
    }

    public void addImage(ImageBean imageBean){
        this.imageBeen.add(imageBean);
    }
    public void addImages(List<ImageBean> imageBean){
        this.imageBeen.addAll(imageBean);
    }
    public boolean removeImage(ImageBean imageBean){
        return this.imageBeen.remove(imageBean);
    }
    public void clearImage(){
        this.imageBeen.clear();
    }
    public void setCompressQuality(int quality){
        this.compressQuality = quality;
    }
    public void setCleanCacheAfterUpload(boolean cleanCacheAfterUpload){
        this.cleanCacheAfterUpload = cleanCacheAfterUpload;
    }

    /* 开始上传图片 */
    public boolean uploadImages() {
        if(imageBeen == null || imageBeen.size() == 0)
            return false;

        Observable.OnSubscribe<List<String>> onSubscribe = new Observable.OnSubscribe<List<String>>() {

//            List<String> resultImageKeys = new ArrayList<>();
            Map<Integer, String> resultImageKeys = new HashMap<>();

            @Override
            public void call(Subscriber<? super List<String>> subscriber) {
                // 保存图片
                for(int i = 0; i < imageBeen.size(); i++){
                    String cachePath = cacheImageDir + i + "_" + System.currentTimeMillis();
                    if(!compressAndSaveImage(imageBeen.get(i).getPath(), cachePath, compressQuality)){
                        imageCompressFail(imageBeen.get(i).getKey());
//                        imageUploadFail(null);
                        return;
                    }
                    imageBeen.get(i).setPath(cachePath);
                    imageCompressSuccess(imageBeen.get(i).getKey());
                }
                imageCompressComplete();
                // 上传图片
                for(int i = 0; i < imageBeen.size(); i++){
                    final int position = i;
                    UploadLogic upload = new UploadLogic(context, imageBeen.get(position).getPath(), imageBeen.get(position).getKey());
                    upload.setCallBack(new UploadLogic.UploadCallBack() {
                        @Override
                        public void done(boolean success) {
                            if(!success){
                                imageUploadFail(imageBeen.get(position).getKey());
                                return;
                            }
                        }
                        @Override
                        public void uploadSuccess(String url) {
//                            resultImageKeys.add(url);
//                            imageUploadSuccess(imageBeen.get(position).getKey(), url);
//                            if(resultImageKeys.size() == imageBeen.size()){
//                                imageUploadComplete(resultImageKeys);
//                            }
                            resultImageKeys.put(position, url);
                            imageUploadSuccess(imageBeen.get(position).getKey(), url);
                            if(resultImageKeys.size() == imageBeen.size()){
                                List<String> imgKeys = new ArrayList<>();
                                for(int i = 0; i < resultImageKeys.size(); i++)
                                    imgKeys.add(resultImageKeys.get(i));
                                imageUploadComplete(imgKeys);
                            }
                        }
                    });
                    upload.uploadImage();
                }
            }
        };
        Subscriber<List<String>> subscriber = new Subscriber<List<String>>(){
            @Override
            public void onCompleted() {}
            @Override
            public void onError(Throwable e) {
                imageUploadFail(null);
            }
            @Override
            public void onNext(List<String> data) {}
        };
        Observable.create(onSubscribe)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
        return true;
    }

    /* 压缩并保存图片 */
    private boolean compressAndSaveImage(String imagePath, String savePath, int quality){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;

        // 获取图片的大小信息
        BitmapFactory.decodeFile(imagePath, options);
        // 对图片进行缩放
        float imSampleSize = calculateInSampleSize(options);
        Bitmap bitmap = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath),
                (int)(options.outWidth/imSampleSize + 0.5),
                (int)(options.outHeight/imSampleSize + 0.5),
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT
        );
        // 判断图片格式
        Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;
        if(imagePath.endsWith(".png") || imagePath.endsWith(".PNG")) {
            compressFormat = Bitmap.CompressFormat.PNG;
        }
        // 对图片进行质量压缩并保存
        boolean isSuccess = ImageUtil.saveBitmap(bitmap, savePath, compressFormat, quality);
        if(!bitmap.isRecycled())
            bitmap.recycle();
        return isSuccess;
    }
    /* 计算缩放比例 */
    protected float calculateInSampleSize(BitmapFactory.Options options){
        float inSimpleSize = 1.0f;
        int maxSize = Math.max(options.outWidth, options.outHeight);
        int minSize = Math.min(options.outWidth, options.outHeight);

        if(maxSize >= 1280.0f){
            inSimpleSize = maxSize / 1280.0f;
        } else if(maxSize >= 960.0f) {
            inSimpleSize = maxSize / 960.0f;
            if(minSize/inSimpleSize < 640.0f){
                inSimpleSize = minSize / 640.0f;
            }
            if(maxSize/inSimpleSize >= 1280.0f){
                inSimpleSize = maxSize/1280.0f;
            }
        } else if(maxSize >= 640.0f){
            inSimpleSize = minSize / 640.0f;
            if(maxSize/inSimpleSize >= 1280.0f){
                inSimpleSize = maxSize/1280.0f;
            }
        } else{
            inSimpleSize = maxSize/640.0f;
        }
        return inSimpleSize;
    }
    /* 删除文件夹 */
    private void deleteDir(File dir) {
        if (dir == null || !dir.exists() || !dir.isDirectory())
            return;
        for (File file : dir.listFiles()) {
            if (file.isFile())
                file.delete();
            else if (file.isDirectory())
                deleteDir(file);
        }
        dir.delete();
    }
    /* 图片压缩并保存成功 */
    private void imageCompressSuccess(String key){
        if(this.imageUploadCallBack != null)
            this.imageUploadCallBack.imageCompressSuccess(key);
    }
    /* 图片压缩并保存失败 */
    private void imageCompressFail(String key){
        if(this.imageUploadCallBack != null)
            this.imageUploadCallBack.imageCompressFail(key);
    }
    /* 图片压缩并保存完成 */
    private void imageCompressComplete(){
        if(this.imageUploadCallBack != null)
            this.imageUploadCallBack.imageCompressComplete();
    };
    /* 图片上传成功 */
    private void imageUploadSuccess(String key, String resultKey){
        if(this.imageUploadCallBack != null)
            this.imageUploadCallBack.imageUploadSuccess(key, resultKey);
    }
    /* 图片上传失败 */
    private void imageUploadFail(String key){
        if(this.imageUploadCallBack != null)
            this.imageUploadCallBack.imageUploadFail(key);
    }
    /* 全部图片上传完成 */
    private void imageUploadComplete(List<String> resultKeys){
        // 删除图片缓存
        deleteDir(new File(this.cacheImageDir));
        if(this.imageUploadCallBack != null)
            this.imageUploadCallBack.imageUploadComplete(resultKeys);
    }

    private ImageUploadCallBack imageUploadCallBack;
    public void setImageUploadCallBack(ImageUploadCallBack imageUploadCallBack) {
        this.imageUploadCallBack = imageUploadCallBack;
    }
    public interface ImageUploadCallBack{
        void imageCompressFail(String key);
        void imageCompressSuccess(String key);
        void imageCompressComplete();
        void imageUploadFail(String key);
        void imageUploadSuccess(String key, String resultKey);
        void imageUploadComplete(List<String> resultKeys);
    }

    public static class ImageBean{
        private String key;
        private String path;
        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        public String getPath() {
            return path;
        }
        public void setPath(String path) {
            this.path = path;
        }
    }
}
